package gv.project 
{
	import gv.utils.Utils;

	import com.greensock.TweenMax;

	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.geom.Point;

	/**
	 * @author rick
	 */
	public class Taxonomie extends MovieClip 
	{
		private var plantModelArray : Array;
		private var iconArray : Array;
		private var given : PlantButton;
		private var usedButtons : Array = new Array();
		private var allButtons : Array = new Array();
		private var iconField : MovieClip;
		private var fieldX : Number = 50;
		private var fieldW : Number = 450;
		private var fieldY : Number = 50;
		private var fieldH : Number = 450;
		private var givenIndex : Number = -1;
		private var givenModelArray : Array;

		public function Taxonomie()
		{
			init();
		}

		public function init() : void
		{
			plantModelArray = new Array();
			iconArray = new Array();
			
			plantModelArray.push(new PlantModel("Test 1"));
			plantModelArray.push(new PlantModel("Test 2"));
			plantModelArray.push(new PlantModel("Test 3"));
			plantModelArray.push(new PlantModel("Test 4"));
			plantModelArray.push(new PlantModel("Test 5"));
			plantModelArray.push(new PlantModel("Test 6"));
			plantModelArray.push(new PlantModel("Test 7"));
			plantModelArray.push(new PlantModel("Test 8"));
			plantModelArray.push(new PlantModel("Test 9"));
			plantModelArray.push(new PlantModel("Test 10"));
			plantModelArray.push(new PlantModel("Test 11"));
			plantModelArray.push(new PlantModel("Test 12"));
			plantModelArray.push(new PlantModel("Test 13"));
			plantModelArray.push(new PlantModel("Test 14"));
			plantModelArray.push(new PlantModel("Test 15"));
			plantModelArray.push(new PlantModel("Test 16"));
			plantModelArray.push(new PlantModel("Test 17"));
			plantModelArray.push(new PlantModel("Test 18"));
			plantModelArray.push(new PlantModel("Test 19"));
			plantModelArray.push(new PlantModel("Test 20"));
			plantModelArray.push(new PlantModel("Test 21"));
			plantModelArray.push(new PlantModel("Test 22"));
			plantModelArray.push(new PlantModel("Test 23"));
			plantModelArray.push(new PlantModel("Test 24"));
			plantModelArray.push(new PlantModel("Test 25"));
			givenModelArray = Utils.randomizeArray(plantModelArray);
			
			createTaxonomy();
			createTools(0, 0xFFFF00);
			createTools(1, 0x00FFFF);
			createTools(2, 0xFF00FF);
		}

		//		private function nextPlantEvent(event : KeyboardEvent) : void
		//		{
		//			stage.removeEventListener(KeyboardEvent.KEY_DOWN, nextPlantEvent);
		//			removeButtonField();
		//		}
		private function removeButtonField() : void
		{
			for each(var btn:PlantButton in allButtons)
			{
				removeChild(btn);
			}
			for each(var mdl:PlantModel in plantModelArray)
			{
				mdl.plant.setState(0);
			}
			removeChild(given);
			given = null;
			usedButtons = new Array();
			allButtons = new Array();
			createButtonField();
		}

		private function createTools(index : int, color : uint) : void
		{
			var tool : Tool = new Tool(color);
			tool.x = 600 + index * 70;
			tool.y = 500;
			tool.buttonMode = true;
			addChild(tool);
			tool.addEventListener(MouseEvent.CLICK, onToolClick);
			
			var toolTip : ToolTip = new ToolTip(color);
			toolTip.visible = false;
			addChild(toolTip);
			tool.toolTip = toolTip;
		}

		private function onToolClick(event : MouseEvent) : void
		{
			var tool : Tool = event.currentTarget as Tool;
			setMode(tool);
		}

		private function setMode(tool : Tool) : void
		{
			var tooltip : ToolTip = tool.toolTip;
			tooltip.x = stage.mouseX;
			tooltip.y = stage.mouseY;
			tooltip.startDrag(true);
			tooltip.visible = true; 
			
			for each(var btn:PlantButton in allButtons)
			{
				btn.setMode(tool.color);	
			}
		}

		private function createButtonField() : void
		{
			givenIndex++;
			if(givenIndex >= givenModelArray.length)
			{
				givenIndex = 0;
			}
			var index : int = 0;
			given = createPlantButton(index, givenModelArray[givenIndex] as PlantModel);
			index++;
			var usingModels : Array = Utils.selectRandomInArray(plantModelArray, 9, givenIndex);
			for each(var item:PlantModel in usingModels)
			{
				var button : PlantButton = createPlantButton(index, item);
				usedButtons.push(button);
				allButtons.push(button);
				index++;
			}
			given.setState(1);
			updateField();
		}

		private function createPlantButton(index : int, item : PlantModel) : PlantButton
		{
			var button : PlantButton = new PlantButton(item.plant);
			button.x = 70 * (index % 3) + 600;
			button.y = 70 * Math.floor(index / 3) + 50;
			button.setName(item.name);
			button.addEventListener(MouseEvent.CLICK, plantButtonClick);
			addChild(button);
			return button;
		}

		private function updateField() : void
		{
			if(usedButtons.length != 0)	
			{
				var totalX : Number = 0;
				var totalY : Number = 0;
				for each(var plt:PlantButton in usedButtons)
				{
					plt.setState(2);
					totalX += plt.getIconX();
					totalY += plt.getIconY();	
				}
				var gemX : Number = totalX / usedButtons.length;
				var gemY : Number = totalY / usedButtons.length;
				var newX : Number = (gemX + given.getIconX()) / 2;
				var newY : Number = (gemY + given.getIconY()) / 2;
				var pos : Point = getPosByRatio(newX, newY);
				given.getIcon().ratioX = newX;
				given.getIcon().ratioY = newY;
				TweenMax.to(given.getIcon(), .5, {x:pos.x, y:pos.y, onComplete:resizeField});
			}
		}

		private function getPosByRatio(ratioX : Number, ratioY : Number) : Point
		{
			var obj : Point = new Point(0, 0);
			obj.x = fieldX + ratioX * fieldW;
			obj.y = fieldY + ratioY * fieldH;
			return obj;
		}

		private function resizeField() : void
		{
			var minX : Number = 1;
			var minY : Number = 1;
			var maxX : Number = 0;
			var maxY : Number = 0;
			var mX : Number = 1;//multiplier, field resized by mX;
			var mY : Number = 1;
			for each(var plnt : PlantIcon in iconArray)
			{
				minX = (plnt.ratioX < minX) ? plnt.ratioX : minX;
				maxX = (plnt.ratioX > maxX) ? plnt.ratioX : maxX;
				minY = (plnt.ratioY < minY) ? plnt.ratioY : minY;
				maxY = (plnt.ratioY > maxY) ? plnt.ratioY : maxY;
			}
			mX = 1 / (maxX - minX);  
			mY = 1 / (maxY - minY);  
			for each(var plant : PlantIcon in iconArray)
			{
				var newX : Number = (plant.ratioX - minX) * mX;
				var newY : Number = (plant.ratioY - minY) * mY;
				plant.textBox.text = Math.round(newX * 100) + "|" + Math.round(newY * 100) + "";
				var pos : Point = getPosByRatio(newX, newY);
				plant.ratioX = newX;
				plant.ratioY = newY;
				TweenMax.to(plant, .5, {x:pos.x, y:pos.y});
			}
			TweenMax.to({}, .5, {onComplete:idle});
		}

		private function idle() : void
		{
//			stage.removeEventListener(KeyboardEvent.KEY_DOWN, nextPlantEvent);
//			stage.addEventListener(KeyboardEvent.KEY_DOWN, nextPlantEvent);
		}

		private function createTaxonomy() : void
		{
			iconField = new MovieClip();
			addChild(iconField);
			var index : int = 0;
			for each(var mdl:PlantModel in plantModelArray)
			{
				var plant : PlantIcon = createPlant(index, mdl.name);
				iconArray.push(plant);
				iconField.addChild(plant);
				mdl.plant = plant;
				index++;
			}
			createButtonField();
		}

		private function plantButtonClick(event : MouseEvent) : void
		{
			var buttonClicked : PlantButton = event.currentTarget as PlantButton;
			if(buttonClicked == given)
			{
				return;
			}
			
			if(Utils.in_array(buttonClicked, usedButtons))
			{
				if(usedButtons.length < 3)
					return;
				var newUsing : Array = new Array();
				for each(var pi:PlantButton in usedButtons)
				{
					if(pi != event.currentTarget)
					{
						newUsing.push(pi);
					}
				}
				usedButtons = newUsing;
				buttonClicked.setState(0);
			}
			else
			{
				usedButtons.push(buttonClicked);	
			}
			updateField();
		}

		public function createPlant(index : int ,name : String) : PlantIcon
		{
			var newPlant : PlantIcon = new PlantIcon();
			var matrix : Number = Math.floor(Math.sqrt(plantModelArray.length));
			newPlant.ratioX = (index % matrix) / matrix;
			newPlant.ratioY = Math.floor(index / matrix) / matrix;
			var pnt : Point = getPosByRatio(newPlant.ratioX, newPlant.ratioY);
			newPlant.x = pnt.x;
			newPlant.y = pnt.y;
			newPlant.setName(name);
			return newPlant;
		}

		public function get _fieldW() : Number
		{
			return fieldW;
		}

		public function set _fieldW(fieldW : Number) : void
		{
			this.fieldW = fieldW;
		}
	}	
}
